package healthcheck

import (
	"time"

	"github.com/romberli/das/internal/dependency/healthcheck"
	"github.com/romberli/das/pkg/message"
	msghc "github.com/romberli/das/pkg/message/healthcheck"
	"github.com/romberli/go-util/constant"
)

const (
	dbConfigMaxConnections            = "max_connections"
	dbConfigSlaveParallelWorkers      = "slave_parallel_workers"
	dbConfigLogBin                    = "log_bin"
	dbConfigBinlogFormat              = "binlog_format"
	dbConfigBinlogRowImage            = "binlog_row_image"
	dbConfigSyncBinlog                = "sync_binlog"
	dbConfigInnodbFlushLogAtTrxCommit = "innodb_flush_log_at_trx_commit"
	dbConfigGTIDMode                  = "gtid_mode"
	dbConfigEnforceGTIDConsistency    = "enforce_gtid_consistency"
	dbConfigSlaveParallelType         = "slave_parallel_type"
	dbConfigMasterInfoRepository      = "master_info_repository"
	dbConfigRelayLogInfoRepository    = "relay_log_info_repository"
	dbConfigReportHost                = "report_host"
	dbConfigReportPort                = "report_port"
	dbConfigInnodbFlushMethod         = "innodb_flush_method"
	dbConfigInnodbMonitorEnable       = "innodb_monitor_enable"
	dbConfigInnodbPrintAllDeadlocks   = "innodb_print_all_deadlocks"
	dbConfigSlowQueryLog              = "slow_query_log"
	dbConfigPerformanceSchema         = "performance_schema"

	dbConfigMaxConnectionsValid            = 2000
	dbConfigSlaveParallelWorkersValid      = 16
	dbConfigLogBinValid                    = "ON"
	dbConfigBinlogFormatValid              = "ROW"
	dbConfigBinlogRowImageValid            = "FULL"
	dbConfigSyncBinlogValid                = "1"
	dbConfigInnodbFlushLogAtTrxCommitValid = "1"
	dbConfigGTIDModeValid                  = "ON"
	dbConfigEnforceGTIDConsistencyValid    = "ON"
	dbConfigSlaveParallelTypeValid         = "LOGICAL_CLOCK"
	dbConfigMasterInfoRepositoryValid      = "TABLE"
	dbConfigRelayLogInfoRepositoryValid    = "TABLE"
	dbConfigReportHostValid                = constant.EmptyString
	dbConfigReportPortValid                = constant.EmptyString
	dbConfigInnodbFlushMethodValid         = "O_DIRECT"
	dbConfigInnodbMonitorEnableValid       = "ALL"
	dbConfigInnodbPrintAllDeadlocksValid   = "ON"
	dbConfigSlowQueryLogValid              = "ON"
	dbConfigPerformanceSchemaValid         = "ON"
)

var (
	_ healthcheck.OperationInfo  = (*OperationInfo)(nil)
	_ healthcheck.Variable       = (*GlobalVariable)(nil)
	_ healthcheck.Table          = (*Table)(nil)
	_ healthcheck.PrometheusData = (*PrometheusData)(nil)

	dbConfigVariableNames = map[string]string{
		dbConfigLogBin:                    dbConfigLogBinValid,
		dbConfigBinlogFormat:              dbConfigBinlogFormatValid,
		dbConfigBinlogRowImage:            dbConfigBinlogRowImageValid,
		dbConfigSyncBinlog:                dbConfigSyncBinlogValid,
		dbConfigInnodbFlushLogAtTrxCommit: dbConfigInnodbFlushLogAtTrxCommitValid,
		dbConfigGTIDMode:                  dbConfigGTIDModeValid,
		dbConfigEnforceGTIDConsistency:    dbConfigEnforceGTIDConsistencyValid,
		dbConfigSlaveParallelType:         dbConfigSlaveParallelTypeValid,
		dbConfigMasterInfoRepository:      dbConfigMasterInfoRepositoryValid,
		dbConfigRelayLogInfoRepository:    dbConfigRelayLogInfoRepositoryValid,
		dbConfigReportHost:                dbConfigReportHostValid,
		dbConfigReportPort:                dbConfigReportPortValid,
		dbConfigInnodbFlushMethod:         dbConfigInnodbFlushMethodValid,
		// dbConfigInnodbMonitorEnable:       dbConfigInnodbMonitorEnableValid,
		dbConfigInnodbPrintAllDeadlocks: dbConfigInnodbPrintAllDeadlocksValid,
		dbConfigSlowQueryLog:            dbConfigSlowQueryLogValid,
		dbConfigPerformanceSchema:       dbConfigPerformanceSchemaValid,
	}
)

type OperationInfo struct {
	operationID              int
	loginName                string
	mysqlServerHostIP        string
	mysqlServerPortNum       int
	mysqlServerServerName    string
	mysqlServerServiceName   string
	monitorSystemSystemType  int
	monitorSystemHostIP      string
	monitorSystemPortNum     int
	monitorSystemPortNumSlow int
	monitorSystemBaseURL     string
	startTime                time.Time
	endTime                  time.Time
	step                     time.Duration
	callbackAddr             string
}

// NewOperationInfo returns a new healthcheck.OperationInfo
func NewOperationInfo(operationID int,
	loginName string, mysqlServerHostIP string, mysqlServerPortNum int, mysqlServerServerName, mysqlServerServiceName string,
	monitorSystemSystemType int, monitorSystemHostIP string, monitorSystemPortNum int, monitorSystemPortNumSlow int, monitorSystemBaseURL string,
	startTime, endTime time.Time, step time.Duration, callbackAddr string) healthcheck.OperationInfo {
	return newOperationInfo(
		operationID,
		loginName,
		mysqlServerHostIP,
		mysqlServerPortNum,
		mysqlServerServerName,
		mysqlServerServiceName,
		monitorSystemSystemType,
		monitorSystemHostIP,
		monitorSystemPortNum,
		monitorSystemPortNumSlow,
		monitorSystemBaseURL,
		startTime,
		endTime,
		step,
		callbackAddr,
	)
}

// newOperationInfo returns a new *OperationInfo
func newOperationInfo(operationID int,
	loginName string, mysqlServerHostIP string, mysqlServerPortNum int, mysqlServerServerName, mysqlServerServiceName string,
	monitorSystemSystemType int, monitorSystemHostIP string, monitorSystemPortNum int, monitorSystemPortNumSlow int, monitorSystemBaseURL string,
	startTime, endTime time.Time, step time.Duration, callbackAddr string) *OperationInfo {
	return &OperationInfo{
		operationID:              operationID,
		loginName:                loginName,
		mysqlServerHostIP:        mysqlServerHostIP,
		mysqlServerPortNum:       mysqlServerPortNum,
		mysqlServerServerName:    mysqlServerServerName,
		mysqlServerServiceName:   mysqlServerServiceName,
		monitorSystemSystemType:  monitorSystemSystemType,
		monitorSystemHostIP:      monitorSystemHostIP,
		monitorSystemPortNum:     monitorSystemPortNum,
		monitorSystemPortNumSlow: monitorSystemPortNumSlow,
		monitorSystemBaseURL:     monitorSystemBaseURL,
		startTime:                startTime,
		endTime:                  endTime,
		step:                     step,
		callbackAddr:             callbackAddr,
	}
}

// GetOperationID returns the operation identity
func (oi *OperationInfo) GetOperationID() int {
	return oi.operationID
}

// GetUser returns the login user
func (oi *OperationInfo) GetLoginName() string {
	return oi.loginName
}

// GetMySQLServerHostIP returns the mysql server host ip
func (oi *OperationInfo) GetMySQLServerHostIP() string {
	return oi.mysqlServerHostIP
}

// GetMySQLServerPortNum returns the mysql server port number
func (oi *OperationInfo) GetMySQLServerPortNum() int {
	return oi.mysqlServerPortNum
}

// GetMySQLServerServerName returns the mysql server server name
func (oi *OperationInfo) GetMySQLServerServerName() string {
	return oi.mysqlServerServerName
}

// GetMySQLServerServiceName returns the mysql server service name
func (oi *OperationInfo) GetMySQLServerServiceName() string {
	return oi.mysqlServerServiceName
}

// GetMonitorSystemSystemType returns the system type of the monitor system
func (oi *OperationInfo) GetMonitorSystemSystemType() int {
	return oi.monitorSystemSystemType
}

// GetMonitorSystemHostIP returns the monitor system host IP
func (oi *OperationInfo) GetMonitorSystemHostIP() string {
	return oi.monitorSystemHostIP
}

// GetMonitorSystemPortNum returns the monitor system port number
func (oi *OperationInfo) GetMonitorSystemPortNum() int {
	return oi.monitorSystemPortNum
}

// GetMonitorSystemPortNumSlow returns the monitor system port number for slow log
func (oi *OperationInfo) GetMonitorSystemPortNumSlow() int {
	return oi.monitorSystemPortNumSlow
}

// GetMonitorSystemBaseURL returns the monitor system base URL
func (oi *OperationInfo) GetMonitorSystemBaseURL() string {
	return oi.monitorSystemBaseURL
}

// GetStartTime returns the start time
func (oi *OperationInfo) GetStartTime() time.Time {
	return oi.startTime
}

// GetEndTime returns the end time
func (oi *OperationInfo) GetEndTime() time.Time {
	return oi.endTime
}

// GetStep returns the step
func (oi *OperationInfo) GetStep() time.Duration {
	return oi.step
}

// GetCallbackAddr returns the call back server address
func (oi *OperationInfo) GetCallbackAddr() string {
	return oi.callbackAddr
}

type OperationHistory struct {
	ID             int       `middleware:"id" json:"id"`
	LoginName      string    `middleware:"login_name" json:"login_name"`
	HostIP         string    `middleware:"host_ip" json:"host_ip"`
	PortNum        int       `middleware:"port_num" json:"port_num"`
	StartTime      time.Time `middleware:"start_time" json:"start_time"`
	EndTime        time.Time `middleware:"end_time" json:"end_time"`
	Step           int       `middleware:"step" json:"step"`
	Status         int       `middleware:"status" json:"status"`
	Message        string    `middleware:"message" json:"message"`
	DelFlag        int       `middleware:"del_flag" json:"del_flag"`
	CreateTime     time.Time `middleware:"create_time" json:"create_time"`
	LastUpdateTime time.Time `middleware:"last_update_time" json:"last_update_time"`
}

// NewOperationHistory returns healthcheck.OperationHistory
func NewOperationHistory(id int, loginName string, hostIP string, portNum int, startTime, endTime time.Time, step, status int, message string,
	delFlag int, createTime, lastUpdateTime time.Time) healthcheck.OperationHistory {
	return newOperationHistory(id, loginName, hostIP, portNum, startTime, endTime, step, status, message, delFlag, createTime, lastUpdateTime)
}

// NewEmptyOperationHistory returns healthcheck.OperationHistory with empty value
func NewEmptyOperationHistory() healthcheck.OperationHistory {
	return &OperationHistory{}
}

// newOperationHistory returns *OperationHistory
func newOperationHistory(id int, loginName string, hostIP string, portNum int, startTime, endTime time.Time, step, status int, message string,
	delFlag int, createTime, lastUpdateTime time.Time) *OperationHistory {
	return &OperationHistory{
		ID:             id,
		LoginName:      loginName,
		HostIP:         hostIP,
		PortNum:        portNum,
		StartTime:      startTime,
		EndTime:        endTime,
		Step:           step,
		Status:         status,
		Message:        message,
		DelFlag:        delFlag,
		CreateTime:     createTime,
		LastUpdateTime: lastUpdateTime,
	}
}

// GetID returns the identity
func (oh *OperationHistory) GetID() int {
	return oh.ID
}

// GetLoginName returns the user login name
func (oh *OperationHistory) GetLoginName() string {
	return oh.LoginName
}

// GetHostIP returns the host ip of mysql server
func (oh *OperationHistory) GetHostIP() string {
	return oh.HostIP
}

// GetPortNum returns the port number of mysql server
func (oh *OperationHistory) GetPortNum() int {
	return oh.PortNum
}

// GetStartTime returns the start time
func (oh *OperationHistory) GetStartTime() time.Time {
	return oh.StartTime
}

// GetEndTime returns the end time
func (oh *OperationHistory) GetEndTime() time.Time {
	return oh.EndTime
}

// GetStep returns the step, the unit is seconds
func (oh *OperationHistory) GetStep() int {
	return oh.Step
}

// GetStatus returns the status
func (oh *OperationHistory) GetStatus() int {
	return oh.Status
}

// GetMessage returns the message
func (oh *OperationHistory) GetMessage() string {
	return oh.Message
}

// GetDelFlag returns the delete flag
func (oh *OperationHistory) GetDelFlag() int {
	return oh.DelFlag
}

// GetCreateTime returns the create time
func (oh *OperationHistory) GetCreateTime() time.Time {
	return oh.CreateTime
}

// GetLastUpdateTime returns the last update time
func (oh *OperationHistory) GetLastUpdateTime() time.Time {
	return oh.LastUpdateTime
}

// DefaultItemConfig include all data for a item
type DefaultItemConfig struct {
	ID                          int       `middleware:"id" json:"id"`
	ItemName                    string    `middleware:"item_name" json:"item_name"`
	ItemWeight                  int       `middleware:"item_weight" json:"item_weight"`
	LowWatermark                float64   `middleware:"low_watermark" json:"low_watermark"`
	HighWatermark               float64   `middleware:"high_watermark" json:"high_watermark"`
	Unit                        float64   `middleware:"unit" json:"unit"`
	ScoreDeductionPerUnitHigh   float64   `middleware:"score_deduction_per_unit_high" json:"score_deduction_per_unit_high"`
	MaxScoreDeductionHigh       float64   `middleware:"max_score_deduction_high" json:"max_score_deduction_high"`
	ScoreDeductionPerUnitMedium float64   `middleware:"score_deduction_per_unit_medium" json:"score_deduction_per_unit_medium"`
	MaxScoreDeductionMedium     float64   `middleware:"max_score_deduction_medium" json:"max_score_deduction_medium"`
	DelFlag                     int       `middleware:"del_flag" json:"del_flag"`
	CreateTime                  time.Time `middleware:"create_time" json:"create_time"`
	LastUpdateTime              time.Time `middleware:"last_update_time" json:"last_update_time"`
}

// NewDefaultItemConfig returns new healthcheck.ItemConfig
func NewDefaultItemConfig(itemName string, itemWeight int, lowWatermark float64, highWatermark float64, unit float64,
	scoreDeductionPerUnitHigh float64, maxScoreDeductionHigh float64, scoreDeductionPerUnitMedium float64, maxScoreDeductionMedium float64) healthcheck.ItemConfig {
	return newDefaultItemConfig(
		itemName,
		itemWeight,
		lowWatermark,
		highWatermark,
		unit,
		scoreDeductionPerUnitHigh,
		maxScoreDeductionHigh,
		scoreDeductionPerUnitMedium,
		maxScoreDeductionMedium,
	)
}

// newDefaultItemConfig returns new *DefaultItemConfig
func newDefaultItemConfig(itemName string, itemWeight int, lowWatermark float64, highWatermark float64, unit float64,
	scoreDeductionPerUnitHigh float64, maxScoreDeductionHigh float64, scoreDeductionPerUnitMedium float64, maxScoreDeductionMedium float64) *DefaultItemConfig {
	return &DefaultItemConfig{
		ItemName:                    itemName,
		ItemWeight:                  itemWeight,
		LowWatermark:                lowWatermark,
		HighWatermark:               highWatermark,
		Unit:                        unit,
		ScoreDeductionPerUnitHigh:   scoreDeductionPerUnitHigh,
		MaxScoreDeductionHigh:       maxScoreDeductionHigh,
		ScoreDeductionPerUnitMedium: scoreDeductionPerUnitMedium,
		MaxScoreDeductionMedium:     maxScoreDeductionMedium,
	}
}

// NewEmptyDefaultItemConfig returns a new healthcheck.DefaultItemConfig with empty value
func NewEmptyDefaultItemConfig() healthcheck.ItemConfig {
	return &DefaultItemConfig{}
}

// GetID returns the identity
func (dic *DefaultItemConfig) GetID() int {
	return dic.ID
}

// GetItemName returns the item name
func (dic *DefaultItemConfig) GetItemName() string {
	return dic.ItemName
}

// GetItemWeight returns the item weight
func (dic *DefaultItemConfig) GetItemWeight() int {
	return dic.ItemWeight
}

// GetLowWatermark returns the low watermark
func (dic *DefaultItemConfig) GetLowWatermark() float64 {
	return dic.LowWatermark
}

// GetHighWatermark returns the high watermark
func (dic *DefaultItemConfig) GetHighWatermark() float64 {
	return dic.HighWatermark
}

// GetUnit returns the unit
func (dic *DefaultItemConfig) GetUnit() float64 {
	return dic.Unit
}

// GetScoreDeductionPerUnitHigh returns the score deduction per unit high
func (dic *DefaultItemConfig) GetScoreDeductionPerUnitHigh() float64 {
	return dic.ScoreDeductionPerUnitHigh
}

// GetMaxScoreDeductionHigh returns the max score deduction high
func (dic *DefaultItemConfig) GetMaxScoreDeductionHigh() float64 {
	return dic.ScoreDeductionPerUnitHigh
}

// GetScoreDeductionPerUnitMedium returns the score deduction per unit medium
func (dic *DefaultItemConfig) GetScoreDeductionPerUnitMedium() float64 {
	return dic.ScoreDeductionPerUnitMedium
}

// GetMaxScoreDeductionMedium returns the max score deduction medium
func (dic *DefaultItemConfig) GetMaxScoreDeductionMedium() float64 {
	return dic.MaxScoreDeductionMedium
}

// GetDelFlag returns the delete flag
func (dic *DefaultItemConfig) GetDelFlag() int {
	return dic.DelFlag
}

// GetCreateTime returns the create time
func (dic *DefaultItemConfig) GetCreateTime() time.Time {
	return dic.CreateTime
}

// GetLastUpdateTime returns the last update time
func (dic *DefaultItemConfig) GetLastUpdateTime() time.Time {
	return dic.LastUpdateTime
}

// DefaultEngineConfig is a map of DefaultItemConfig
type DefaultEngineConfig map[string]healthcheck.ItemConfig

// NewEmptyDefaultEngineConfig returns a new empty DefaultItemConfig
func NewEmptyDefaultEngineConfig() healthcheck.EngineConfig {
	return DefaultEngineConfig{}
}

// GetItemConfig returns healthcheck.ItemConfig with given item name
func (dec DefaultEngineConfig) GetItemConfig(item string) healthcheck.ItemConfig {
	return dec[item]
}

// SetItemConfig sets item config with given item and config
func (dec DefaultEngineConfig) SetItemConfig(item string, config healthcheck.ItemConfig) {
	dec[item] = config
}

// Validate validates if engine configuration is valid
func (dec DefaultEngineConfig) Validate() error {
	itemWeightSummary := constant.ZeroInt
	// validate defaultEngineConfig exits items
	if len(dec) == constant.ZeroInt {
		return message.NewMessage(msghc.ErrHealthcheckDefaultEngineEmpty)
	}
	for itemName, defaultItemConfig := range dec {
		// validate item weight
		if defaultItemConfig.GetItemWeight() > defaultHundred || defaultItemConfig.GetItemWeight() < constant.ZeroInt {
			return message.NewMessage(msghc.ErrHealthcheckItemWeightItemInvalid, itemName, defaultItemConfig.GetItemWeight())
		}
		// validate low watermark
		if defaultItemConfig.GetLowWatermark() < constant.ZeroInt {
			return message.NewMessage(msghc.ErrHealthcheckLowWatermarkItemInvalid, itemName, defaultItemConfig.GetLowWatermark())
		}
		// validate high watermark
		if defaultItemConfig.GetHighWatermark() < defaultItemConfig.GetLowWatermark() {
			return message.NewMessage(msghc.ErrHealthcheckHighWatermarkItemInvalid, itemName, defaultItemConfig.GetHighWatermark())
		}
		// validate unit
		if defaultItemConfig.GetUnit() < constant.ZeroInt {
			return message.NewMessage(msghc.ErrHealthcheckUnitItemInvalid, itemName, defaultItemConfig.GetUnit())
		}
		// validate score deduction per unit high
		if defaultItemConfig.GetScoreDeductionPerUnitHigh() > defaultHundred || defaultItemConfig.GetScoreDeductionPerUnitHigh() < constant.ZeroInt || defaultItemConfig.GetScoreDeductionPerUnitHigh() > defaultItemConfig.GetMaxScoreDeductionHigh() {
			return message.NewMessage(msghc.ErrHealthcheckScoreDeductionPerUnitHighItemInvalid, itemName, defaultItemConfig.GetScoreDeductionPerUnitHigh())
		}
		// validate max score deduction high
		if defaultItemConfig.GetMaxScoreDeductionHigh() > defaultHundred || defaultItemConfig.GetMaxScoreDeductionHigh() < constant.ZeroInt {
			return message.NewMessage(msghc.ErrHealthcheckMaxScoreDeductionHighItemInvalid, itemName, defaultItemConfig.GetMaxScoreDeductionHigh())
		}
		// validate score deduction per unit medium
		if defaultItemConfig.GetScoreDeductionPerUnitMedium() > defaultHundred || defaultItemConfig.GetScoreDeductionPerUnitMedium() < constant.ZeroInt || defaultItemConfig.GetScoreDeductionPerUnitMedium() > defaultItemConfig.GetMaxScoreDeductionMedium() {
			return message.NewMessage(msghc.ErrHealthcheckScoreDeductionPerUnitMediumItemInvalid, itemName, defaultItemConfig.GetScoreDeductionPerUnitMedium())
		}
		// validate max score deduction medium
		if defaultItemConfig.GetMaxScoreDeductionMedium() > defaultHundred || defaultItemConfig.GetMaxScoreDeductionMedium() < constant.ZeroInt {
			return message.NewMessage(msghc.ErrHealthcheckMaxScoreDeductionMediumItemInvalid, itemName, defaultItemConfig.GetMaxScoreDeductionMedium())
		}
		itemWeightSummary += defaultItemConfig.GetItemWeight()
	}
	// validate item weigh count is 100
	if itemWeightSummary != defaultHundred {
		return message.NewMessage(msghc.ErrHealthcheckItemWeightSummaryInvalid, itemWeightSummary)
	}

	return nil
}

// GlobalVariable encapsulates k-v pairs for global variable
type GlobalVariable struct {
	VariableName  string `middleware:"variable_name" json:"variable_name"`
	VariableValue string `middleware:"variable_value" json:"variable_value"`
}

// NewEmptyGlobalVariable returns a new *GlobalVariables
func NewEmptyGlobalVariable() *GlobalVariable {
	return &GlobalVariable{}
}

// NewGlobalVariable returns a *GlobalVariable
func NewGlobalVariable(name, value string) *GlobalVariable {
	return &GlobalVariable{
		VariableName:  name,
		VariableValue: value,
	}
}

func (gv *GlobalVariable) GetName() string {
	return gv.VariableName
}

func (gv *GlobalVariable) GetValue() string {
	return gv.VariableValue
}

type Variable struct {
	Name   string `middleware:"name" json:"name"`
	Value  string `middleware:"value" json:"value"`
	Advice string `middleware:"advice" json:"advice"`
}

func NewVariable(variableName, currentValue, advice string) *Variable {
	return &Variable{
		Name:   variableName,
		Value:  currentValue,
		Advice: advice,
	}
}

type Table struct {
	DBName    string  `middleware:"db_name" json:"db_name"`
	TableName string  `middleware:"table_name" json:"table_name"`
	TableRows int     `middleware:"table_rows" json:"table_rows"`
	TableSize float64 `middleware:"table_size" json:"table_size"`
}

func NewTable(db, name string, rows int, size float64) healthcheck.Table {
	return &Table{
		DBName:    db,
		TableName: name,
		TableRows: rows,
		TableSize: size,
	}
}

func NewEmptyTable() healthcheck.Table {
	return &Table{}
}

// GetDBName returns the db name
func (t *Table) GetDBName() string {
	return t.DBName
}

// GetTableName returns the table name
func (t *Table) GetTableName() string {
	return t.TableName
}

// GetTableRows returns the table rows
func (t *Table) GetTableRows() int {
	return t.TableRows
}

// GetTableSize returns the table size
func (t *Table) GetTableSize() float64 {
	return t.TableSize
}

type FileSystem struct {
	MountPoint string `middleware:"mount_point" json:"mount_point"`
	Device     string `middleware:"device" json:"device"`
}

// NewFileSystem returns a new healthcheck.FileSystem
func NewFileSystem(mountPoint, device string) healthcheck.FileSystem {
	return &FileSystem{
		MountPoint: mountPoint,
		Device:     device,
	}
}

// GetMountPoint returns the mount point
func (fs *FileSystem) GetMountPoint() string {
	return fs.MountPoint
}

// GetDevice returns the device
func (fs *FileSystem) GetDevice() string {
	return fs.Device
}

type SlaveStatus struct {
	isSlave   bool
	isRunning bool
}

// NewSlaveStatus returns a new healthcheck.SlaveStatus
func NewSlaveStatus(isSlave, isRunning bool) healthcheck.SlaveStatus {
	return &SlaveStatus{
		isSlave:   isSlave,
		isRunning: isRunning,
	}
}

// IsSlave returns if the server is slave
func (ss *SlaveStatus) IsSlave() bool {
	return ss.isSlave
}

// IsRunning returns if the slave thread is running
func (ss *SlaveStatus) IsRunning() bool {
	return ss.isRunning
}

type PrometheusData struct {
	Timestamp string  `middleware:"timestamp" json:"timestamp"`
	Value     float64 `middleware:"value" json:"value"`
}

func NewPrometheusData(ts string, value float64) healthcheck.PrometheusData {
	return &PrometheusData{
		Timestamp: ts,
		Value:     value,
	}
}

// NewEmptyPrometheusData returns a new healthcheck.PrometheusData
func NewEmptyPrometheusData() healthcheck.PrometheusData {
	return &PrometheusData{}
}

// GetTimestamp returns the timestamp
func (pd *PrometheusData) GetTimestamp() string {
	return pd.Timestamp
}

// GetValue returns the value
func (pd *PrometheusData) GetValue() float64 {
	return pd.Value
}
